<template>
  <div class="environment-monitor">
    <div class="header-actions">
      <h1>漏洞验证</h1>
    </div>
    <el-card shadow="hover" style="margin-bottom: 20px">
      <div class="selectBox">
        <span>验证环境</span>
        <el-select
          v-model="value"
          placeholder="请选择漏洞验证的环境"
          style="width: 240px"
        >
          <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </div>
      <div class="selectBox">
        <span>漏洞</span>
        <el-select
          v-model="value"
          placeholder="请选择验证的漏洞"
          style="width: 240px"
        >
          <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </div>
      <div>
        <el-button type="primary">执行验证</el-button>
      </div>
    </el-card>

    <div style="display: flex">
      <!-- 验证状态卡片 -->
      <el-card style="width: 300px; margin-right: 20px">
        <template #header>
          <div class="card-header">
            <span>验证状态</span>
          </div>
        </template>

        <div class="verification-status">
          <el-timeline style="max-width: 600px">
            <el-timeline-item timestamp="2018/4/12" placement="top">
              <el-card class="timeline_card">
                <h4>Update Github template</h4>
                <p>Tom committed 2018/4/12 20:46</p>
              </el-card>
            </el-timeline-item>
            <el-timeline-item timestamp="2018/4/3" placement="top">
              <el-card class="timeline_card">
                <h4>Update Github template</h4>
                <p>Tom committed 2018/4/3 20:46</p>
              </el-card>
            </el-timeline-item>
            <el-timeline-item timestamp="2018/4/2" placement="top">
              <el-card class="timeline_card">
                <h4>Update Github template</h4>
                <p>Tom committed 2018/4/2 20:46</p>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </div>
      </el-card>

      <div style="flex: 1">
        <!-- 资源使用监控 -->
        <div class="resource-monitor">
          <el-card>
            <template #header>
              <div class="card-header">
                <span>CPU 使用率</span>
                <span class="value-text"
                  >{{ monitorData.cpuUsage || "0" }}%</span
                >
              </div>
            </template>
            <div class="chart-container">
              <div ref="cpuChartRef" class="chart"></div>
            </div>
          </el-card>

          <el-card>
            <template #header>
              <div class="card-header">
                <span>内存使用率</span>
                <span class="value-text"
                  >{{ monitorData.memoryUsage || "0" }}%</span
                >
              </div>
            </template>
            <div class="chart-container">
              <div ref="memoryChartRef" class="chart"></div>
            </div>
          </el-card>
        </div>

        <!-- 网络流量监控 -->
        <el-card>
          <template #header>
            <div class="card-header">
              <span>网络流量</span>
            </div>
          </template>
          <div class="chart-container">
            <div ref="networkChartRef" class="chart network-chart"></div>
          </div>
        </el-card>

        <!-- 实时日志 -->
        <el-card>
          <template #header>
            <div class="card-header">
              <span>实时日志</span>
              <div class="log-actions">
                <el-dropdown @command="handleLogFilter">
                  <el-button type="default" size="small">
                    筛选
                    <el-icon class="el-icon--right"><arrow-down /></el-icon>
                  </el-button>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item command="all">全部</el-dropdown-item>
                      <el-dropdown-item command="info">信息</el-dropdown-item>
                      <el-dropdown-item command="warning"
                        >警告</el-dropdown-item
                      >
                      <el-dropdown-item command="error">错误</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
                <el-button type="primary" size="small" @click="exportLogs"
                  >导出</el-button
                >
              </div>
            </div>
          </template>

          <div class="logs-container">
            <div
              v-for="(log, index) in filteredLogs"
              :key="index"
              class="log-item"
              :class="getLogClass(log.level)"
            >
              <span class="log-time">{{ log.time }}</span>
              <span class="log-content">{{ log.content }}</span>
            </div>
            <div v-if="filteredLogs.length === 0" class="empty-logs">
              暂无日志记录
            </div>
          </div>
        </el-card>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, onBeforeUnmount } from "vue";
import { ArrowDown } from "@element-plus/icons-vue";
import * as echarts from "echarts/core";
import { LineChart } from "echarts/charts";
import {
  TooltipComponent,
  GridComponent,
  LegendComponent,
} from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
import { ElMessage } from "element-plus";

const options = ref([
  { value: "env1", label: "验证环境1" },
  { value: "env2", label: "验证环境2" },
  { value: "env3", label: "验证环境3" },
]);
const value = ref("");
const verificationStatus = ref(true);

// 注册必需的组件
echarts.use([
  LineChart,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  CanvasRenderer,
]);

// 引用和状态
const cpuChartRef = ref(null);
const memoryChartRef = ref(null);
const networkChartRef = ref(null);
const cpuChart = ref(null);
const memoryChart = ref(null);
const networkChart = ref(null);
const logFilter = ref("all");
const monitorInterval = ref(null);
const logsInterval = ref(null);

// 监控数据
const monitorData = reactive({
  startTime: "10:00:00",
  verifyTime: "10:00:30",
  endTime: null,
  status: "running",
  cpuUsage: 78,
  memoryUsage: 42,
  networkTraffic: [],
  cpuData: Array(30).fill(0),
  memoryData: Array(30).fill(0),
  timeData: Array(30)
    .fill("")
    .map((_, i) => {
      const date = new Date();
      date.setSeconds(date.getSeconds() - (30 - i) * 10);
      return date.toLocaleTimeString("zh-CN", {
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
      });
    }),
});

// 日志数据
const logs = ref([
  { time: "10:00:00", level: "info", content: "启动验证进程" },
  { time: "10:00:01", level: "info", content: "加载验证环境配置" },
  { time: "10:00:30", level: "info", content: "开始执行漏洞验证" },
  { time: "10:00:45", level: "warning", content: "检测到异常网络连接" },
  { time: "10:01:00", level: "error", content: "目标端口无响应" },
]);

// 过滤后的日志
const filteredLogs = computed(() => {
  if (logFilter.value === "all") {
    return logs.value;
  }
  return logs.value.filter((log) => log.level === logFilter.value);
});

// 当前步骤索引
const currentStepIndex = computed(() => {
  if (monitorData.status === "completed") return 2;
  if (monitorData.verifyTime) return 1;
  return 0;
});

// 初始化图表
const initCharts = () => {
  // CPU 图表
  cpuChart.value = echarts.init(cpuChartRef.value);
  const cpuOption = {
    tooltip: {
      trigger: "axis",
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      data: monitorData.timeData,
      boundaryGap: false,
    },
    yAxis: {
      type: "value",
      min: 0,
      max: 100,
      name: "%",
    },
    series: [
      {
        name: "CPU",
        type: "line",
        data: monitorData.cpuData,
        areaStyle: {
          color: {
            type: "linear",
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              {
                offset: 0,
                color: "rgba(75, 192, 192, 0.8)",
              },
              {
                offset: 1,
                color: "rgba(75, 192, 192, 0.1)",
              },
            ],
          },
        },
        itemStyle: {
          color: "#4bc0c0",
        },
        smooth: true,
      },
    ],
  };
  cpuChart.value.setOption(cpuOption);

  // 内存图表
  memoryChart.value = echarts.init(memoryChartRef.value);
  const memoryOption = {
    tooltip: {
      trigger: "axis",
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      data: monitorData.timeData,
      boundaryGap: false,
    },
    yAxis: {
      type: "value",
      min: 0,
      max: 100,
      name: "%",
    },
    series: [
      {
        name: "内存",
        type: "line",
        data: monitorData.memoryData,
        areaStyle: {
          color: {
            type: "linear",
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              {
                offset: 0,
                color: "rgba(116, 119, 231, 0.8)",
              },
              {
                offset: 1,
                color: "rgba(116, 119, 231, 0.1)",
              },
            ],
          },
        },
        itemStyle: {
          color: "#7477e7",
        },
        smooth: true,
      },
    ],
  };
  memoryChart.value.setOption(memoryOption);

  // 网络流量图表
  networkChart.value = echarts.init(networkChartRef.value);
  const networkOption = {
    tooltip: {
      trigger: "axis",
    },
    legend: {
      data: ["上行", "下行"],
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      boundaryGap: false,
      data: monitorData.timeData,
    },
    yAxis: {
      type: "value",
      name: "MB/s",
    },
    series: [
      {
        name: "上行",
        type: "line",
        stack: "Total",
        data: [
          0.5, 0.8, 1.2, 2.5, 2.8, 3.0, 3.8, 4.5, 5.0, 6.2, 4.8, 4.0, 3.5, 2.9,
          3.5, 4.0, 4.5, 5.0, 5.5, 7.0, 6.8, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 1.5,
          2.0, 2.5,
        ],
        areaStyle: {
          color: {
            type: "linear",
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              {
                offset: 0,
                color: "rgba(58, 184, 147, 0.8)",
              },
              {
                offset: 1,
                color: "rgba(58, 184, 147, 0.1)",
              },
            ],
          },
        },
        itemStyle: {
          color: "#3ab893",
        },
        smooth: true,
      },
      {
        name: "下行",
        type: "line",
        stack: "Total",
        data: [
          0.3, 0.5, 0.9, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 3.9, 3.5, 3.0, 2.5,
          3.0, 3.5, 3.0, 4.0, 4.5, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5, 0.9,
          0.5, 0.3,
        ],
        areaStyle: {
          color: {
            type: "linear",
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              {
                offset: 0,
                color: "rgba(86, 152, 235, 0.8)",
              },
              {
                offset: 1,
                color: "rgba(86, 152, 235, 0.1)",
              },
            ],
          },
        },
        itemStyle: {
          color: "#5698eb",
        },
        smooth: true,
      },
    ],
  };
  networkChart.value.setOption(networkOption);

  // 窗口大小变化时重绘图表
  window.addEventListener("resize", handleResize);
};

// 处理窗口大小变化
const handleResize = () => {
  cpuChart.value && cpuChart.value.resize();
  memoryChart.value && memoryChart.value.resize();
  networkChart.value && networkChart.value.resize();
};

// 模拟数据更新
const updateMonitorData = async () => {
  try {
    // 模拟数据更新
    const now = new Date();
    const timeStr = now.toLocaleTimeString("zh-CN", {
      hour: "2-digit",
      minute: "2-digit",
      second: "2-digit",
    });

    // 更新时间数据
    monitorData.timeData.shift();
    monitorData.timeData.push(timeStr);

    // 更新CPU数据
    const newCpuValue = Math.floor(70 + Math.random() * 20);
    monitorData.cpuData.shift();
    monitorData.cpuData.push(newCpuValue);
    monitorData.cpuUsage = newCpuValue;

    // 更新内存数据
    const newMemoryValue = Math.floor(35 + Math.random() * 15);
    monitorData.memoryData.shift();
    monitorData.memoryData.push(newMemoryValue);
    monitorData.memoryUsage = newMemoryValue;

    // 更新图表
    if (cpuChart.value) {
      cpuChart.value.setOption({
        xAxis: {
          data: monitorData.timeData,
        },
        series: [
          {
            data: monitorData.cpuData,
          },
        ],
      });
    }

    if (memoryChart.value) {
      memoryChart.value.setOption({
        xAxis: {
          data: monitorData.timeData,
        },
        series: [
          {
            data: monitorData.memoryData,
          },
        ],
      });
    }

    if (networkChart.value) {
      const upData = [];
      const downData = [];
      for (let i = 0; i < 30; i++) {
        upData.push((Math.random() * 5 + 2).toFixed(1));
        downData.push((Math.random() * 4 + 1).toFixed(1));
      }

      networkChart.value.setOption({
        xAxis: {
          data: monitorData.timeData,
        },
        series: [
          {
            data: upData,
          },
          {
            data: downData,
          },
        ],
      });
    }
  } catch (error) {
    console.error("获取监控数据失败", error);
  }
};

// 拉取日志数据
const fetchLogs = async () => {
  try {
    // 模拟随机添加一条日志
    if (Math.random() > 0.7) {
      const now = new Date();
      const timeStr = now.toLocaleTimeString("zh-CN", {
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
      });
      const levels = ["info", "warning", "error"];
      const level = levels[Math.floor(Math.random() * levels.length)];
      const contents = [
        "检查系统服务状态",
        "扫描目标端口",
        "尝试建立连接",
        "发送测试数据包",
        "检测到异常响应",
        "目标系统无响应",
        "连接被重置",
        "验证攻击向量",
        "漏洞利用成功",
        "目标系统崩溃",
      ];
      const content = contents[Math.floor(Math.random() * contents.length)];

      logs.value.push({
        time: timeStr,
        level,
        content,
      });

      // 保持日志不超过100条
      if (logs.value.length > 100) {
        logs.value.shift();
      }
    }
  } catch (error) {
    console.error("获取日志失败", error);
  }
};

// 格式化时间
const formatTime = (timeStr) => {
  return timeStr || "--:--";
};

// 获取日志样式类
const getLogClass = (level) => {
  return {
    "log-info": level === "info",
    "log-warning": level === "warning",
    "log-error": level === "error",
  };
};

// 处理日志过滤
const handleLogFilter = (command) => {
  logFilter.value = command;
};

// 导出日志
const exportLogs = () => {
  // 导出日志逻辑
  ElMessage.success("日志导出成功");
};

// 初始化定时更新
const initIntervals = () => {
  // 清除可能存在的旧定时器
  clearIntervals();

  // 每5秒更新一次监控数据
  monitorInterval.value = setInterval(updateMonitorData, 5000);

  // 每3秒更新一次日志
  logsInterval.value = setInterval(fetchLogs, 3000);
};

// 清除定时器
const clearIntervals = () => {
  if (monitorInterval.value) {
    clearInterval(monitorInterval.value);
    monitorInterval.value = null;
  }

  if (logsInterval.value) {
    clearInterval(logsInterval.value);
    logsInterval.value = null;
  }
};

// 组件挂载时初始化
onMounted(() => {
  // 初始化图表和数据
  initCharts();
  updateMonitorData();
  fetchLogs();
  initIntervals();
});

// 组件卸载前清理
onBeforeUnmount(() => {
  clearIntervals();
  window.removeEventListener("resize", handleResize);

  // 销毁图表实例
  cpuChart.value && cpuChart.value.dispose();
  memoryChart.value && memoryChart.value.dispose();
  networkChart.value && networkChart.value.dispose();
});
</script>

<style lang="scss" scoped>
.environment-monitor {
  padding: 20px;
  .header-actions {
    margin-bottom: 20px;
  }

  .selectBox{
    margin-right: 50px;
  }

  ::v-deep {
    .el-card__body {
      width: 100%;
      display: flex;
      > div {
        > span {
          margin-right: 15px;
        }
      }
    }
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .value-text {
      font-size: 16px;
      font-weight: bold;
    }
  }

  .verification-status {
    padding: 10px 0;
  }

  .resource-monitor {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 15px;
    margin-bottom: 15px;
  }

  .chart-container {
    width: 100%;

    .chart {
      height: 250px;
      width: 100%;
    }

    .network-chart {
      height: 300px;
    }
  }

  .logs-container {
    width: 100%;
    height: 300px;
    overflow-y: auto;
    font-family: monospace;

    .log-item {
      padding: 4px 8px;
      border-bottom: 1px solid #f0f0f0;
      font-size: 13px;
      display: flex;

      .log-time {
        color: #909399;
        width: 80px;
        flex-shrink: 0;
      }

      .log-content {
        flex: 1;
      }

      &.log-info {
        color: #606266;
      }

      &.log-warning {
        color: #e6a23c;
        background-color: rgba(230, 162, 60, 0.05);
      }

      &.log-error {
        color: #f56c6c;
        background-color: rgba(245, 108, 108, 0.05);
      }
    }

    .empty-logs {
      text-align: center;
      color: #909399;
      padding: 40px 0;
    }
  }

  .log-actions {
    display: flex;
    gap: 10px;
  }
}
</style>
